package com.imooc.restaurant.service;

import com.dong.basic.constant.Constant;
import com.dong.basic.dto.OrderMessageDTO;
import com.dong.basic.tools.ConnectionTools;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.restaurant.dao.ProductDao;
import com.imooc.restaurant.dao.RestaurantDao;
import com.imooc.restaurant.enums.ProductStatus;
import com.imooc.restaurant.enums.RestaurantStatus;
import com.imooc.restaurant.po.ProductPO;
import com.imooc.restaurant.po.RestaurantPO;
import com.rabbitmq.client.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

@Service
@Slf4j
public class OrderMessageRestaurantService {
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private ProductDao productDao;
    @Autowired
    private RestaurantDao restaurantDao;
    @Async
    public void handleMsg(){
        final ConnectionFactory connectionFactory = ConnectionTools.getConnectionFactory();
        try (Connection connection = connectionFactory.newConnection()){
            final Channel channel = connection.createChannel();
            channel.exchangeDeclare(Constant.Exchange.RESTAURANT, BuiltinExchangeType.DIRECT, true, false, null);
            channel.queueDeclare(Constant.Queue.RESTAURANT, true, false, false, null);
            //绑定    饭店交换机==> restaurant==> 饭店队列
            channel.queueBind(Constant.Queue.RESTAURANT, Constant.Exchange.RESTAURANT, Constant.BindingKey.RESTAURANT);
            channel.basicConsume(Constant.Queue.RESTAURANT,true,deliverCallback,(consumerTag -> {
                log.error("consumerTag: {}",consumerTag);
            }));
            while (true) {
                Thread.sleep(10000);
            }
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

    DeliverCallback deliverCallback = this::handle;

    private void handle(String consumerTag, Delivery message) {
        log.error("restaurant handlerMsg");
        String msg = new String(message.getBody());
        final ConnectionFactory connectionFactory = ConnectionTools.getConnectionFactory();
        try {
            final OrderMessageDTO orderMessageDTO = objectMapper.readValue(msg, OrderMessageDTO.class);
            final ProductPO productPO = productDao.selectProduct(orderMessageDTO.getProductId());
            final RestaurantPO restaurantPO = restaurantDao.selectRestaurant(productPO.getRestaurantId());

            if (ProductStatus.AVAILABLE.equals(productPO.getStatus()) && RestaurantStatus.OPEN.equals(restaurantPO.getStatus())) {

                orderMessageDTO.setConfirmed(true);
                orderMessageDTO.setPrice(productPO.getPrice());

            } else {
                orderMessageDTO.setConfirmed(false);
            }
            try (Connection connection = connectionFactory.newConnection()){
                final Channel channel = connection.createChannel();

                String orderMsgStr = objectMapper.writeValueAsString(orderMessageDTO);
                channel.basicPublish(Constant.Exchange.RESTAURANT, Constant.RoutingKey.ORDER, null, orderMsgStr.getBytes());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }  catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}
